package com.geor.gcv.core.process;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.opencv.core.Mat;
import org.opencv.core.Point;

import com.geor.gcv.core.mat.ProcessImageDefalut;
import com.geor.gcv.core.ui.PanelObservable;
import com.geor.gcv.core.ui.ImagePanel;

/**
 * 测试的处理 目前没有用处
 * 
 * @author geor.lusongnan
 */
public class GrayLevelProcess extends Process {
	Process chain;
	int level;

	public GrayLevelProcess(Process chain, int level) {
		this.chain = chain;
		this.level = level;
	}

	@Override
	public String getProcessName() {
		return chain.getProcessName() + "-->" + "灰度等级划分!";
	}

	@Override
	public Mat process() {
		Mat mat = chain.process();
		Map<Integer, List<Integer>> maps = new LinkedHashMap<Integer, List<Integer>>();
		for (int l = 1; l <= level; l++) {
			PexContainer container = new PexContainer(mat, l);
			container.process();
			maps.put(l, container.getLists());
		}
		PanelObservable obserable = new PanelObservable(new ProcessImageDefalut());
		ImagePanel panel = new ImagePanel("识别结果", 1100, 1000, obserable);
		panel.init();
		for (int level : maps.keySet()) {
			Consolidator consolidator = new Consolidator(mat);
			consolidator.setLists(maps.get(Math.abs(level - 11)));
		}
		return mat;
	}

}

class PexContainer {
	Mat src;
	List<Integer> lists = new ArrayList<Integer>();
	int level;

	public PexContainer(Mat src, int level) {
		this.src = src;
		this.level = level;
	}

	public List<Integer> getLists() {
		return lists;
	}

	public void process() {
		int incremental = 255 / level;
		for (int l = 0; l <= level; l++) {
			lists.add(incremental * l);
		}

		for (int row = 0; row < src.rows(); row++) {
			for (int col = 0; col < src.cols(); col++) {
				int pex = (int) src.get(row, col)[0];
				for (int i = 1; i < lists.size(); i++) {
					if (pex < lists.get(i) && lists.get(i - 1) > pex) {
						break;
					}
				}
			}
		}
		lists.set(lists.size() - 1, 255);
	}

}

class Consolidator {
	Mat src;
	List<Integer> lists = new ArrayList<Integer>();
	long index = 0;

	public Consolidator(Mat src) {
		this.src = src;
	}

	public long getIndex() {
		return index;
	}

	public void setLists(List<Integer> lists) {
		this.lists = lists;
	}

	public Mat process() {

		for (int row = 1; row < src.rows() - 1; row++) {
			for (int col = 1; col < src.cols() - 1; col++) {
				Point point = new Point(row, col);
				int level = getLevel(point);
				Point point_1 = new Point(row - 1, col - 1);
				if (!setScrPex(level, point, point_1)) {
					index++;
				}

				Point point_2 = new Point(row - 1, col);
				if (!setScrPex(level, point, point_2)) {
					index++;
				}
				Point point_3 = new Point(row - 1, col + 1);
				if (!setScrPex(level, point, point_3)) {
					index++;
				}
				Point point_4 = new Point(row, col - 1);
				if (!setScrPex(level, point, point_4)) {
					index++;
				}
				Point point_5 = new Point(row, col + 1);
				if (!setScrPex(level, point, point_5)) {
					index++;
				}
				Point point_6 = new Point(row + 1, col - 1);
				if (!setScrPex(level, point, point_6)) {
					index++;
				}
				Point point_7 = new Point(row + 1, col);
				if (!setScrPex(level, point, point_7)) {
					index++;
				}
				Point point_8 = new Point(row + 1, col + 1);
				if (!setScrPex(level, point, point_8)) {
					index++;
				}
			}
		}
		index++;
		return src;
	}

	private int getLevel(Point point) {
		int pex = (int) src.get((int) point.x, (int) point.y)[0];
		for (int i = 1; i < lists.size(); i++) {
			if (pex <= lists.get(i) && pex >= lists.get(i - 1)) {
				return i;
			}
		}

		throw new RuntimeException("------");
	}

	private boolean setScrPex(int level, Point point, Point setPoint) {
		if (level == getLevel(setPoint)) {
			src.put((int) setPoint.x, (int) setPoint.y, lists.get(level));
			return true;
		}
		return false;
	}

}